/**
* @brief 操作系统内核功能接口文件
* @author chenjl
* @date 2019.07.01
*/

#include "anOs.h"

int32  __svc(0x10)  CallDevIo(uint32 *p);
void   __svc(0x11)  CallTimeFcn(uint32 fn,uint32 p);
uint32 __svc(0x12)  CallGetSysInfo(uint32 fn);
int32 __svc(0x13)   CallEventFcn(uint32 *p);

#ifndef TEST_OS_EVN

//typedef void (*handle_copy_fn)(uint32 romaddr,uint32 ramaddr,uint32 len);
typedef void (*handle_fn)(uint32 romaddr,uint32 ramaddr,uint32 len);

typedef struct {
//    uint32* data_rom_addr;
//    uint32* data_ram_addr;
//    uint32 data_size;
//    uint32 fc_addr;
    
    uint32 end_addr;
    uint32 ram_addr;
    uint32 byte_size;
    uint32 fc_def;
}RegionTableStr;

/**
* @brief 执行一组数据段操作功能
*/
static void DataAndBss(RegionTableStr *pTable)
{
    handle_fn call_fn;
    call_fn = (handle_fn)(pTable->fc_def+1);          
    call_fn(pTable->end_addr,pTable->ram_addr,pTable->byte_size);
}

int main(void)
{
    extern void AppMain(void);
    extern RegionTableStr Region$$Table$$Base ;
    extern RegionTableStr Region$$Table$$Limit;
    
    RegionTableStr *Table = &Region$$Table$$Base;          
    
    /*拷贝DATA和清除BSS*/
    while(Table < &Region$$Table$$Limit)
    {        
        DataAndBss(Table);
        Table = Table + 1;
    }

    /*3.进入应用程序*/
    AppMain();
    
    /*4.程序退出时，删除当前任务*/
    TaskKill();
    while(1)
    {
        __WFI();
    }
}
#endif

int32 dev_open(char* name,uint32 param)
{
    uint32 parameters[4];
    
    parameters[0] = 1;
    parameters[1] = (uint32)name;
    parameters[2] = param;    
    
    return CallDevIo(parameters);
}

int32 dev_read(int32 handle,void *pdata,int32 len)
{
    uint32 parameters[4];
    
    parameters[0] = 2;
    parameters[1] = handle;
    parameters[2] = (uint32)pdata; 
    parameters[3] = len; 
    
    return CallDevIo(parameters);
}

int32 dev_write(int32 handle,void *pdata,int32 len)
{
    uint32 parameters[4];
    
    parameters[0] = 3;
    parameters[1] = handle;
    parameters[2] = (uint32)pdata; 
    parameters[3] = len; 
    
    return CallDevIo(parameters);
}

int32 dev_ctrl(int32 handle,uint32 code,uint32 value)
{
    uint32 parameters[4];
    
    parameters[0] = 4;
    parameters[1] = handle;
    parameters[2] = code;
    parameters[3] = value;
    
    return CallDevIo(parameters);
}

__weak void AppMain(void)
{
}

void TaskWait(uint32 ms)
{
    CallTimeFcn(1,ms);
}

void TaskWaitNxtPeriod(void)
{
    CallTimeFcn(2,0);
}

void TaskDelay(uint32 us)
{
    CallTimeFcn(3,us);
}

void TaskKill(void)
{
    CallTimeFcn(4,0);
}

uint32 GetSystemTimeMs(void)
{
    return CallGetSysInfo(1);
}

uint32 GetCpuPayload(void)
{
    return CallGetSysInfo(2);
}


int32 CreateEvent(char* name)
{
    uint32 p[3];
    p[0] = 1;
    p[1] = (uint32)name;
    return CallEventFcn(p);
}

void WaitEvent(int32 handle,int32 timeout)
{
    uint32 p[3];
    p[0] = 2;
    p[1] = handle;
    p[2] = timeout;
    CallEventFcn(p);
}

void SetEvent(int32 handle)
{
    uint32 p[3];
    p[0] = 3;
    p[1] = handle;
    CallEventFcn(p);
}



